package com.itbaizhan.myshiro.realm;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itbaizhan.myshiro.domain.Permission;
import com.itbaizhan.myshiro.domain.Users;
import com.itbaizhan.myshiro.mapper.UserMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

//这是用户realm
//自定义realm   token：n.	代币; (用以启动某些机器或用作支付方式的)专用辅币; 代价券; 赠券; 礼券;
// 象征，标志，表示，信物;
//继承AuthorizingRealm
public class MyRealm extends AuthorizingRealm {
    @Autowired
    private UserMapper userMapper;
    //处定义认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户名
        //把参数强转为userPasswordToken
        UsernamePasswordToken token1 = (UsernamePasswordToken) authenticationToken;
        String username = token1.getUsername();
        //根据用户名查询用户
        QueryWrapper<Users> wrapper = new QueryWrapper<Users>().eq("username",username);
        Users users = userMapper.selectOne(wrapper);
        //将查询到的用户封装为身份信息
        if(users == null){
            throw new UnknownAccountException("用户不存在");
        }
        //参数1：查询到的用户  参数2：用户密码  参数3：  参数4：realm名
        return new SimpleAuthenticationInfo(users,
                users.getPassword(),
                ByteSource.Util.bytes(users.getSalt()), //把干拢数据（盐）放进去
                "MyRealm");
    }

    //自定义授权方法
    /*拿到用户的认证信息,从用户的id查询到权限，遍历权限对象，将所有权限交给shiro管理*/
    /*在shiroConfig.java中的配置过虑器（shiroFilterFactoryBean）中配置鉴权过虑器   要写在/**之前，否则认证都无法通过
        最后写控制器（访问的路径）*/

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权。。。。。。");
        //拿到用户的认证信息  从上面的 SimpleAuthenticationInfo知道认证的是Users类型，所以可以强转
        Users users = (Users)principalCollection.getPrimaryPrincipal();
        //从数据库中查询权限
        List<Permission> permissionList = userMapper.findPermissionById(users.getUid());
        //遍历权限对象，将所有权限交给shiro管理
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for(Permission permission:permissionList){
            //在Realm进行授权时，将权限字符串保存到对象中  AuthorizationInfo
            authorizationInfo.addStringPermission(permission.getUrl());
        }
        return authorizationInfo;
    }
}
/*Shiro可以根据用户拥有的权限，控制具体资源的访问，这一过程称为鉴权。在Shiro中，可以通过过滤器进行鉴权配置：
*过滤器	过滤器类	                            说明
roles	RolesAuthorizationFilter	    角色授权过滤器，验证用户是否拥有某角色
perms（常用）	PermissionsAuthorizationFilter	权限授权过滤器，验证用户是否拥有某权限
port	PortFilter	                    端口过滤器，表示可以通过的端口，如果配置端口为80，而用户访问该页面是非80，自动将请求端口改为80并重定向到该80端口
rest	HttpMethodPermissionFilter	    rest风格过滤器，自动根据请求方法构建权限字符串
ssl	    SslFilter	                    SSL过滤器，只有请求协议是https才能通过，否则自动跳转会https端口（443） */